# myapp.spec
import sys
from pathlib import Path
from typing import List
from shutil import copyfile
from PyInstaller import __main__ as pyi

import uvicorn
from pydantic import BaseModel

# FastAPI 应用程序的主文件路径
main_file = Path("main.py").resolve()

# 打包成 exe 文件后，将资源文件复制到 dist 目录下
resources = [
    "templates",
    "static",
]

for resource in resources:
    src = Path(resource).resolve()
    dst = Path("dist") / resource
    if src.exists():
        if src.is_dir():
            dst.mkdir(parents=True, exist_ok=True)
        else:
            dst.parent.mkdir(parents=True, exist_ok=True)
        copyfile(src, dst)

# 在此处定义 FastAPI 应用程序的配置
class Settings(BaseModel):
    app_name: str = "FastAPI"
    debug: bool = False
    reload: bool = False
    log_level: str = "info"
    workers: int = 1
    host: str = "0.0.0.0"
    port: int = 8000

settings = Settings()

# 在此处定义启动 FastAPI 应用程序的函数
def start_fastapi_app():
    sys.path.insert(0, str(main_file.parent))
    module_name = main_file.stem
    module = __import__(module_name)
    app = getattr(module, "app")
    uvicorn.run(
        app,
        host=settings.host,
        port=settings.port,
        log_level=settings.log_level,
        debug=settings.debug,
        reload=settings.reload,
        workers=settings.workers,
    )

# 在此处定义打包时需要排除的模块或文件列表
excludes: List[str] = []

# 在此处定义打包时需要包含的数据文件或目录
datas: List[tuple] = [
    (str(main_file), "."),
    ("dist/templates", "templates"),
    ("dist/static", "static"),
]

# 在此处定义打包时需要添加的 Python 模块或包
hiddenimports: List[str] = [
    "main",
]

# 在此处定义 block_cipher 变量
block_cipher = None

# 获取当前脚本的文件路径
current_file = Path(sys.argv[0]).resolve()

# 定义 PyInstaller 打包的配置
a = Analysis(
    [str(main_file)],
    pathex=[str(current_file.parent)],
    binaries=[],
    datas=datas,
    hiddenimports=hiddenimports,
    hookspath=[],
    runtime_hooks=[],
    excludes=excludes,
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    exclude_binaries=True,
    name=f"{settings.app_name}",
    debug=settings.debug,
    strip=False,
    upx=False,
    console=False,
)

# ...
a = pyi.run([
	'--name', f"{settings.app_name}",
	'--onefile',
	'--windowed',
	str(main_file)
])